package cz.muni.fi.pb138.avradiation.visualisation.chart;

import cz.muni.fi.pb138.avradiation.Sensor.Sensor;
import java.awt.image.BufferedImage;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

/**
 * Drawing XY chart from measured values in sensor(s)
 *
 * @author Vladimir Cerven <v.cerven@gmail.com>
 */
public class ChartXYImpl implements ChartXY {

    /** Default width of chart */
    private static final int DEFAULT_WIDTH = 800;

    /** Default height of chart */
    private static final int DEFAULT_HEIGHT = 500;

    @Override
    public BufferedImage drawChart(Sensor sensor) {
        return drawChart(sensor, DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }

    @Override
    public BufferedImage drawChart(Sensor sensor, int width, int height) {
        if (sensor == null) {
            throw new IllegalArgumentException("Sensor is null");
        }
        if (sensor.getMeasuredValues() == null) {
            throw new IllegalArgumentException("Measured values are null");
        }
        List<Sensor> sensors = new ArrayList<Sensor>();
        sensors.add(sensor);
        return drawChart(sensors, width, height);
    }

    @Override
    public BufferedImage drawChart(List<Sensor> sensors) {
        return drawChart(sensors, DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }

    @Override
    public BufferedImage drawChart(List<Sensor> sensors, int width, int height) {
        if (sensors == null) {
            throw new IllegalArgumentException("Sensors is null");
        }
        if (sensors.isEmpty()) {
            throw new IllegalArgumentException("Sensors is empty");
        }
        if (width <= 5 || height <= 5) {
            throw new IllegalArgumentException("Sizes are too small");
        }
        TimeSeriesCollection dataset = new TimeSeriesCollection();

        for (int i = 0; i < sensors.size(); i++) {
            dataset.addSeries(createTimeSeriesFromSensor(sensors.get(i)));
        }

        JFreeChart chart = ChartFactory.createTimeSeriesChart(
                "AVRadiation Chart",
                "Date",
                sensors.get(0).getUnit(),
                dataset,
                true,
                true,
                false);

        XYPlot plot = (XYPlot) chart.getPlot();
        DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setDateFormatOverride(new SimpleDateFormat("dd.MM. HH:mm"));

        return chart.createBufferedImage(width, height);
    }

    private TimeSeries createTimeSeriesFromSensor(Sensor sensor) {
        TimeSeries series = new TimeSeries(sensor.getName());
        Iterator<Long> valuesIterator = sensor.getMeasuredValues().keySet().iterator();
        Long time = null;
        Date date = null;
        BigDecimal value = null;
        RegularTimePeriod period = null;
        while (valuesIterator.hasNext()) {
            time = valuesIterator.next();
            date = new Date(time);
            period = new Millisecond(date);
            series.add(period, sensor.getMeasuredValues().get(time));
        }
        return series;
    }
}
